package com.sysware.p2m.oracleclient.util;

import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.datasource.DataSourceFactory;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class DBUtil {

    private static Logger logger = LoggerFactory.getLogger(DBUtil.class);

    private DBUtil(){

    }

    /**
     * https://blog.csdn.net/owen_william/article/details/51813165 MyBatis基于Java API配置
     *
     * @param jdbcDriver
     * @param url
     * @param username
     * @param password
     * @param xmlMapperResources
     * @return
     * @throws RuntimeException
     */
    public static SqlSession getMybatisSqlSession(String jdbcDriver, String url, String username, String password, String... xmlMapperResources){
        Properties properties = new Properties();
        properties.put("jdbcdriver", jdbcDriver);
        properties.put("url", url);
        properties.put("username", username);
        properties.put("password", password);
        SqlSessionFactory sessionFactory = buildSqlSessionFactory(jdbcDriver, url, username, password, xmlMapperResources);
        return sessionFactory.openSession();
    }

    /**
     * @param jdbcDriver         jdbc驱动
     * @param url                数据库连接
     * @param username           用户名
     * @param password           密码
     * @param xmlMapperResources mybatis mapper文件
     * @return
     */
    public static SqlSessionFactory buildSqlSessionFactory(String jdbcDriver, String url, String username, String password, String... xmlMapperResources) {
        Configuration configuration = new Configuration();
        try {
            DataSourceFactory dataSourceFactory = (DataSourceFactory) configuration.getTypeAliasRegistry().resolveAlias("POOLED").newInstance();
            Properties properties = new Properties();
            properties.put("driver", jdbcDriver);
            properties.put("url", url);
            properties.put("username", username);
            properties.put("password", password);
            dataSourceFactory.setProperties(properties);

            TransactionFactory transactionFactory = new JdbcTransactionFactory();

            Environment.Builder environmentBuilder = new Environment.Builder("development")
                    .transactionFactory(transactionFactory)
                    .dataSource(dataSourceFactory.getDataSource());
            configuration.setEnvironment(environmentBuilder.build());
        } catch (Exception e) {
            logger.error("", e);
        }

        loadMapperResource(configuration, xmlMapperResources);

        return new SqlSessionFactoryBuilder().build(configuration);
    }

    /**
     * 解析mybatis xml mapper配置信息
     *
     * @param configuration
     * @param xmlMapperResources
     */
    private static void loadMapperResource(Configuration configuration, String... xmlMapperResources) {
        if (xmlMapperResources == null || xmlMapperResources.length < 1) return;
        for (String xmlMapperResource : xmlMapperResources) {
            if (isEmpty(xmlMapperResource) || isEmpty(xmlMapperResource.trim())) continue;
            xmlMapperResource = xmlMapperResource.trim();
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream(xmlMapperResource);
            } catch (IOException e) {
                // ignore, resource is not required
            }
            if (inputStream != null) {
                XMLMapperBuilder xmlParser = new XMLMapperBuilder(inputStream, configuration, xmlMapperResource, configuration.getSqlFragments());
                xmlParser.parse();
            }
        }
    }

    private static boolean isEmpty(String str) {
        return (str == null || str.length() == 0);
    }

}
